#ifndef _TESTPRIMES_H_
#define _TESTPRIMES_H_

#include "cppunit/TestFixture.h"             // TestFixture
#include "cppunit/extensions/HelperMacros.h" // CPPUNIT_TEST, CPPUNIT_TEST_SUITE

struct TestPrimes : CppUnit::TestFixture {

	/**
	 * define your test cases
	 */

	void test_app_impossible () {
		i =  1;
		eval();
		std::ostringstream out;
		print(out);
		CPPUNIT_ASSERT(out.str() == "Impossible.\n");
	}

	void test_app_i_is_odd () {
		i =  11;
		eval();
		std::ostringstream out;
		print(out);
		CPPUNIT_ASSERT(out.str() == "2 3 3 3\n");
	}

	void test_app_i_is_even () {
		i =  12;
		eval();
		std::ostringstream out;
		print(out);
		CPPUNIT_ASSERT(out.str() == "2 2 3 5\n");
	}

	void test_impossible() {
		i = 7;
		eval();
		CPPUNIT_ASSERT(is_impossible);

		i = 8;
		eval();
		CPPUNIT_ASSERT(! is_impossible);
	}

	void test_is_prime() {
		CPPUNIT_ASSERT(is_prime(7));
		CPPUNIT_ASSERT(is_prime(101));
		CPPUNIT_ASSERT(! is_prime(12));
		CPPUNIT_ASSERT(! is_prime(11 * 13));
		CPPUNIT_ASSERT(! is_prime(89201 * 13));
	}

	void test_is_prime_big_number() {
		CPPUNIT_ASSERT(is_prime(9250013));
		CPPUNIT_ASSERT(! is_prime(9250019));
		CPPUNIT_ASSERT(! is_prime(9250025));

		CPPUNIT_ASSERT(is_prime(9250643));
		CPPUNIT_ASSERT(! is_prime(9250645));
	}

	void test_bisearch() {
		//in array
		CPPUNIT_ASSERT(bisearch(2, 0, PRIMES_ARRAY_SIZE - 1));
		CPPUNIT_ASSERT(bisearch(3137, 0, PRIMES_ARRAY_SIZE - 1));
		
		//not in array
		CPPUNIT_ASSERT(! bisearch(20, 0, PRIMES_ARRAY_SIZE - 1));
		CPPUNIT_ASSERT(! bisearch(3000, 0, PRIMES_ARRAY_SIZE - 1));
	}
	
	void test_bisearch_implement() {
		//empty range
		CPPUNIT_ASSERT(! bisearch(2, 1, 0));
		//same point
		CPPUNIT_ASSERT(bisearch(2, 0, 0));
		CPPUNIT_ASSERT(! bisearch(3, 0, 0));
		//in between
		CPPUNIT_ASSERT(bisearch(2741, 0, PRIMES_ARRAY_SIZE - 1));
		//not in between
		CPPUNIT_ASSERT(! bisearch(2741, 0, 10));
	}
	
	
	CPPUNIT_TEST_SUITE(TestPrimes);
	
	/**
	 * register your test case
	 */

	CPPUNIT_TEST(test_app_i_is_even);
	CPPUNIT_TEST(test_app_i_is_odd);
	CPPUNIT_TEST(test_app_impossible);
	
	CPPUNIT_TEST(test_impossible);
	
	CPPUNIT_TEST(test_is_prime);
	CPPUNIT_TEST(test_is_prime_big_number);
	CPPUNIT_TEST(test_bisearch);
	CPPUNIT_TEST(test_bisearch_implement);
	
	CPPUNIT_TEST_SUITE_END();
};

#endif /* _TESTPRIMES_H_ */
